/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package lol.clann.bukkit.pluginboot.service;

import lol.clann.bukkit.pluginboot.task.BukkitTimer;
import lol.clann.bukkit.pluginboot.task.Timer;
import lol.clann.clannboot.annotation.inject.Inject;
import lol.clann.clannboot.annotation.svc.Service;

/**
 * 被@Service注解的类,会自动实例化,作为一个service进行管理,并注册到BeanContext中
 */
@Service
public class ServerTick {

    /**
     * 在Service中的,启动时会进行依赖注入
     */
    @Inject
    private Tick tick;
    /**
     * 缓存十秒内的tps
     */
    private float tps = 20;

    /**
     * 返回10秒内的tps
     *
     * @param
     * @return
     */
    public float getTps() {
        return tps;
    }

    /**
     * 计算指定时间内的平均TPS
     *
     * @param second
     * @return
     */
    public float getTps(int second) {
        tps = tick.getTps(second);
        return tps;
    }

    public int getTick() {
        return tick.number_of_ttck;
    }

    /**
     * BukkitTimer的dely和interval单位是tick
     */
    @BukkitTimer(async = false, dely = "1", interval = "1")
    private void doTick() {
        tick.doTick();
    }

    /**
     * Timer的dely和interval单位是ms
     */
    @Timer(async = true, dely = "1000", interval = "1000", name = "刷新tps")
    private void refreshTps() {
        getTps(20);
    }

    /**
     * 等待下一tick
     */
    public void waitNextTick() {
        int n_tick = tick.number_of_ttck;
        while (n_tick == tick.number_of_ttck) {
            wait(tick);
        }
    }

    /**
     * 判断是否已经doTick,如没有就等待下一tick，并在下一tick返回已执行tick数
     *
     * @param n_tick
     * @return
     */
    public int waitNextTick(int n_tick) {
        while (n_tick == tick.number_of_ttck) {
            wait(tick);
        }
        return tick.number_of_ttck;
    }

    /**
     * 等待n个tick 并返回现在的tick数
     *
     * @return
     * @throws InterruptedException
     */
    public int waitTicks(int n) {
        int ticks = tick.number_of_ttck + n;
        while (ticks > tick.number_of_ttck) {
            wait(tick);
        }
        return tick.number_of_ttck;
    }

    private void wait(Object o) {
        try {
            synchronized (o) {
                o.wait();
            }
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 等待大于time毫秒的最小tick数
     *
     * @param time
     */
    public void dely(long time) {
        long end = System.currentTimeMillis() + time;
        while (end > System.currentTimeMillis()) {
            wait(tick);
        }
    }


}
